gusucode.com > VC++ EMF图片浏览器(可读emf、wmf、emz、wmz、png……等)-源码程序 > VC++ EMF图片浏览器(可读emf、wmf、emz、wmz、png……等)-源码程序/code/Src/Client/scwinlib/SCRectPoly.cpp
//Download by http://www.NewXing.com /* * This file is part of the EMFexplorer projet. * Copyright (C) 2004 Smith Charles. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * Extension: for commercial use, apply the Equity Public License, which * adds to the normal terms of the GLPL a condition of donation to the author. * If you are interested in support for this source code, * contact Smith Charles <smith.charles@free.fr> for more information. */ #include "stdafx.h" #include "SCRectPoly.h" #include "SCGenInclude.h" #include SC_INC_GENLIB(SCGenMath.h) #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif void SCRectPolygon::SCRotate(int iAngle, int xc, int yc) { // this is the angle of rotation for y growing down double fAngle = -(iAngle/1800.0f)*SC_PI; double cosAngle = cos(fAngle); double sinAngle = sin(fAngle); POINT *pPt = this->m_Points; int itmpx; for (int i=0; i<4; i++, pPt++) { itmpx = pPt->x; pPt->x = static_cast<int>(0.5f + xc + (itmpx - xc)*cosAngle - (pPt->y - yc)*sinAngle); pPt->y = static_cast<int>(0.5f + yc + (itmpx - xc)*sinAngle + (pPt->y - yc)*cosAngle); } } #ifdef _DEBUG void SCRectPolygon::SCTestDraw(HDC hdc) { // Save position POINT PtPos; MoveToEx(hdc, m_Points[cnr_LT].x, m_Points[cnr_LT].y, &PtPos); // Draw top and right borders HPEN hRedPen = CreatePen(PS_SOLID, 0, m_ColorTopAndRight); HPEN hOldPen = (HPEN)SelectObject(hdc, hRedPen); LineTo(hdc, m_Points[cnr_RT].x, m_Points[cnr_RT].y); LineTo(hdc, m_Points[cnr_RB].x, m_Points[cnr_RB].y); // Draw bottom and left borders HPEN hBluePen = CreatePen(PS_SOLID, 0, m_ColorBottomAndLeft); SelectObject(hdc, hBluePen); LineTo(hdc, m_Points[cnr_LB].x, m_Points[cnr_LB].y); LineTo(hdc, m_Points[cnr_LT].x, m_Points[cnr_LT].y); // Restore position MoveToEx(hdc, PtPos.x, PtPos.y, NULL); SelectObject(hdc, hOldPen); DeleteObject(hRedPen); DeleteObject(hBluePen); } #endif // The thechique used here is as follows: // We want to reflect a point P(xP, yP) about any line given by two points // A(xA, yA) and B(xB, yB). // Let's call P'(xP', yP') the image of P, // O(x, y) the intersection of PP' with AB // W[u, v]=[xB - xA, yB - yA] a directing vector of AB // we the following equations are true: // 1) xP' + xP = 2x => since P' is a reflection of P // 2) yP' + yP = 2y => ditto // 3) (y - yA)u - (x - xA)v = 0 => equation of a line passing by A and B // 4) (x - xP)u + (y - yP)v = 0 => OP and AB are othogonal // Solving these equations yeilds: // // |xP'| | 2u^2 2u.v -2f.v | |xP'| // | | | (----- - 1) (-------) (-------) | | | // | | | d d d | | | // | | | | | | // |yP'| = | 2u.v 2v^2 2f.u | |yP | // | | | (-------) (----- - 1) (-------) | | | // | | | d d d | | | // | | | | | | // |1 | | 0 0 1 | |1 | // // Where: d = u^2 + v^2, and f = u.yA - v.xA; // '^' stands for 'power of', and the dot '.' for multiplication. // This function always reflects about the left border // (going from LB to LT points, which become A and B respectively) void SCRectPolygon::SCComputeReflectionLeft(XFORM& xform) { SCComputeReflection(xform, &m_Points[cnr_LB], &m_Points[cnr_LT]); } // This function always reflects about the top border // (going from LT to RT points, which become A and B respectively) void SCRectPolygon::SCComputeReflectionTop(XFORM& xform) { SCComputeReflection(xform, &m_Points[cnr_LT], &m_Points[cnr_RT]); } // This function always reflects about the right border // (going from RB to RT points, which become A and B respectively) void SCRectPolygon::SCComputeReflectionRight(XFORM& xform) { SCComputeReflection(xform, &m_Points[cnr_RB], &m_Points[cnr_RT]); } // This function always reflects about the bottom border // (going from LB to RB points, which become A and B respectively) void SCRectPolygon::SCComputeReflectionBottom(XFORM& xform) { SCComputeReflection(xform, &m_Points[cnr_LB], &m_Points[cnr_RB]); } // This function always reflects about a line parallel with the top border // at a distance equal to iDeltaY // Caution: use only on a non-rotated SCRectPolygon void SCRectPolygon::SCComputeReflectionBase(XFORM& xform, int iDeltaY) { POINT PtA; PtA.x = m_Points[cnr_LT].x; PtA.y = m_Points[cnr_LT].y + iDeltaY; POINT PtB; PtA.x = m_Points[cnr_RT].x; PtA.y = m_Points[cnr_RT].y + iDeltaY; SCComputeReflection(xform, &PtA, &PtB); } // General reflection void SCRectPolygon::SCComputeReflection(XFORM& xform, POINT* pPtA, POINT* pPtB) { ASSERT(pPtA); ASSERT(pPtB); int u = pPtB->x - pPtA->x; int v = pPtB->y - pPtA->y; int up2 = u*u; int vp2 = v*v; float d = (float)(up2 + vp2); int f = u*pPtA->y - v*pPtA->x; xform.eM11 = (FLOAT)(2.0*up2/d - 1); xform.eM22 = (FLOAT)(2.0*vp2/d - 1); xform.eM12 = xform.eM21 = (FLOAT)(2.0*u*v/d); xform.eDx = (FLOAT)(-2.0*f*v/d); xform.eDy = (FLOAT)(2.0*f*u/d); }